﻿using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.DgnEC;
using Bentley.DgnPlatformNET.Elements;
using CheccCoverplateCulvertAssemble.Conmmon;
using CheccCoverplateCulvertAssemble.Entity;
using CheccCoverplateCulvertAssemble.Intefaces;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CheccCoverplateCulvertAssemble.Entity
{
    public abstract class ConstructingEntity : ICreateEntityModel,  IElementVolumeInfo ,ICreateReplaceMent
    {
        public double distanceFromStart { get; set; }
        public BasicType basicType { get; set; }
        public CulvertComponentType CulvertComponentType { get; }
        public CulvertType CulvertType { get; }
        public ConstructionMethod ConstructionMethod  {get;}
        protected Element coverEntity { get; set; }
        protected BasicConstructor basicConstructor { get; }
        public DMatrix3d dMatrix3D { get; set; }    //涵洞放置矩阵
        public DPoint3d placeDpoint3d { get; set; } //涵洞放置点

        public List<RebarBase> RebarList => this.CreateRebarList();
        public Dictionary<string, ReplaceMentEntity> keyValuePairs { get; set; }
        public ConstructingEntity(BasicConstructor basicConstructor, CulvertType culvertType, ConstructionMethod constructionMethod,CulvertComponentType culvertComponentType)
        {
            this.basicConstructor = basicConstructor;   
            this.distanceFromStart = distanceFromStart; 
            this.CulvertComponentType = culvertComponentType;
            this.CulvertType = culvertType;
            this.ConstructionMethod = constructionMethod; 
        }

        public string EntityEcPropertyInfoFile
        {
            get
            {
                string jsonString = File.ReadAllText(GeneralHelpers.LevelAndMatrialJsonFilePath);
                var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<JObject>(jsonString);
                var culvertTypeInfo = this.CulvertType == CulvertType.BoxCulvert ? "BoxCulvertFiles" : this.CulvertType == CulvertType.CircularCulvert ? "CircularCulvertFiles" : "SlabCulvertFiles";
                var culvertFilePathArray = obj[culvertTypeInfo] as JArray;
                var ecFileName = this.GetEcFileName(this.CulvertComponentType, this.CulvertType);
                return $@"{GeneralHelpers.WorkSpacePath}{culvertFilePathArray[0].ToString().Substring(1)}\{ecFileName}";
            }
        }

        protected string GetEcFileName(CulvertComponentType culvertComponentType, CulvertType culvertType)
        {
            if (culvertComponentType == CulvertComponentType.OrthogonalityCover && culvertType == CulvertType.SlabCulvert) return "盖板涵_正盖板_构造体.csv";
            if (culvertComponentType == CulvertComponentType.HeterotropicCover && culvertType == CulvertType.SlabCulvert) return "盖板涵_斜盖板_构造体.csv";
            //if (culvertType == CulvertType.BoxCulvert && rebarType == RebarType.Ribbed) return "盖板涵_带肋钢筋_构造体.csv";
            //if (culvertType == CulvertType.BoxCulvert && rebarType == RebarType.Ribbed) return "盖板涵_带肋钢筋_构造体.csv";
            //if (culvertType == CulvertType.BoxCulvert && rebarType == RebarType.Ribbed) return "盖板涵_带肋钢筋_构造体.csv";
            //if (culvertType == CulvertType.BoxCulvert && rebarType == RebarType.Ribbed) return "盖板涵_带肋钢筋_构造体.csv";
            return null;
        }
        public virtual List<RebarBase> CreateRebarList()
        {
            return new List<RebarBase>();
        }
        public abstract void CreateEntityModel();
        public abstract void CreateElementECProperty(Element element, List<Tuple<string, CustomProperty.TypeKind, bool, bool>> tuples);
        public abstract void SetECInstanceValue(IDgnECInstance dgnECInstance, List<(string propertyName, string calculationBasis, string computationalFormula)> propertyData);
        public abstract List<(string standardName, string standValue)> CreateStandardECProperty();
        public abstract void SaveStandardECProperty(IDgnECInstance dgnECInstanc);
        public abstract double GetVolumeOfElement(Element element);
    }
}
